package conf

import (
	"context"
	"flag"
	"fmt"
	"github.com/spf13/viper"
	"inventory/internal/auth"
	"inventory/internal/pkg/dada"
	"inventory/internal/pkg/sf"
	"inventory/pkg/cache"
	"inventory/pkg/env"
	"inventory/pkg/log"
	"inventory/pkg/network"
	"inventory/pkg/nsq"
	"inventory/pkg/orm"
	"os"
)

func init() {
	flag.StringVar(&configFile, "c", "cmd/inventory/config.toml", "path of inventory config file.")
}

var (
	configFile string
	// 全局变量Conf
	Conf = &Config{}
)

type Downstream struct {
	ProdURL   string `mapstructure:"prod_url"`
	MemberURL string `mapstructure:"member_url"`
	AdminURL  string `mapstructure:"admin_url"`
	OpenURL   string `mapstructure:"open_url"`
}

type Config struct {
	Env env.Type `mapstructure:"env"`

	ORM           *orm.Config        `mapstructure:"orm"`
	NSQConfig     *nsq.Configuration `mapstructure:"nsq"`
	NetWorkConfig *network.Config    `mapstructure:"network"`
	Cache         *cache.Config      `mapstructure:"cache"`
	Auth          *auth.Config       `mapstructure:"auth"`
	Downstream    *Downstream        `mapstructure:"downstream"`
	Dada          *dada.Config       `mapstructure:"dada"`
	SF            *sf.Config         `mapstructure:"sf"`

	// 服务名称，无需准备
	ServiceName string `mapstructure:"service_name"`
	// 用于本机调试时，确定是否关闭消息消费，默认不开启
	SkipConsume bool `mapstructure:"skip_consume"`
	// 全局第三方配置信息
	GlobalMapping map[string]map[string]string
}

// Start is func to initial log config
func (config *Config) Init(ctx context.Context) error {
	return config.InitByConfigFile(ctx, configFile)
}

// Start is func to initial log config
func (config *Config) InitByConfigFile(ctx context.Context, configFilePath string) error {
	log.FromContext(ctx).Infow("读取配置文件...",
		"body", configFilePath)
	viper.SetConfigFile(configFilePath)
	if err := viper.ReadInConfig(); err != nil {
		return fmt.Errorf("无法读取配置文件: %s", err.Error())
	}
	if err := viper.Unmarshal(&config); err != nil {
		return fmt.Errorf("配置文件格式不正确: %s", err.Error())
	}

	// 默认系统名称
	config.ServiceName = "inventory"
	config.GlobalMapping = make(map[string]map[string]string)

	config.readEnvParams()
	config.NSQConfig.FillConfig()

	if err := config.verify(); err != nil {
		return err
	}
	log.FromContext(ctx).Infow("读取配置文件...完成")
	return nil
}

// 读取环境配置，环境配置 > config文件内容
func (config *Config) readEnvParams() {
	if address, ok := os.LookupEnv("NSQD_ADDRESS"); ok {
		config.NSQConfig.NSQAddress = address
	}
}

// 校验配置文件数据
func (config *Config) verify() (err error) {
	if err = config.Env.Verify(); err != nil {
		return
	}
	if config.Auth == nil {
		err = fmt.Errorf("缺失验签公钥配置")
		return
	} else if err = config.Auth.InitSecret(); err != nil {
		return
	}
	return
}
